package cvut.fit.dpo.builder;

import java.util.Scanner;
import java.util.Stack;

import cvut.fit.dpo.arithmetic.AddOperator;
import cvut.fit.dpo.arithmetic.ArithmeticExpression;
import cvut.fit.dpo.arithmetic.BinaryOperator;
import cvut.fit.dpo.arithmetic.IComponent;
import cvut.fit.dpo.arithmetic.NumericOperand;
import cvut.fit.dpo.arithmetic.SubstractOperator;

public class InOrderBuilder extends Builder {

	@Override
	public ArithmeticExpression Build(String input) {
		Stack<IComponent> compStack = new Stack<IComponent>();
		Stack<BinaryOperator> opStack = new Stack<BinaryOperator>();
		Scanner sc = new Scanner(input);
		String op = "";
		BinaryOperator operator = null;
		
		while(sc.hasNext()){
			if(sc.hasNextInt()) compStack.push(new NumericOperand(sc.nextInt()));
			else{
				op = sc.next();
				if(op.contains("+")){
					operator = new AddOperator(null,null);
					operator.setOperatorPriority(1);
				}
				else if(op.contains("-")){
					operator = new SubstractOperator(null,null);
					operator.setOperatorPriority(1);
				}
				else if(op.contains("(")){
					String pom = "";
					while(sc.hasNext()){
						String str = sc.next();
						if(str.contains(")")) break;
						pom = pom + str + " ";
						
					}
					compStack.push(Build(pom));
					if(sc.hasNext()) continue;
				}
				
				if(!opStack.isEmpty()){
					if(opStack.peek().getOperatorPriority() > operator.getOperatorPriority() ){
						BinaryOperator pom = opStack.pop();
						if(!compStack.isEmpty()) pom.setSecondOperand(compStack.pop());
						else pom.setSecondOperand(null);
						if(!compStack.isEmpty()) pom.setFirstOperand(compStack.pop());
						else pom.setFirstOperand(null);
						compStack.push(new ArithmeticExpression(pom));
					}
				}
				if(sc.hasNext())opStack.push(operator);
			}
			
			if(!sc.hasNext()){
				while(!opStack.isEmpty()){
					BinaryOperator pom = opStack.pop();
					pom.setSecondOperand(compStack.pop());
					pom.setFirstOperand(compStack.pop());
					compStack.push(new ArithmeticExpression(pom));
					
				}
			}
		}
		return (ArithmeticExpression)compStack.pop();
	}

}
